package com.zsyc.controller;

import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.event.ActionEvent;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.animation.PauseTransition;
import javafx.util.Duration;
import java.util.*;
import java.util.logging.Logger;
import java.util.logging.Level;

public class CodeLearningController {
    private static final Logger LOGGER = Logger.getLogger(CodeLearningController.class.getName());
    
    @FXML private ComboBox<String> languageCombo;
    @FXML private ComboBox<Integer> questionCountCombo;
    @FXML private Button startQuizButton;
    
    @FXML private VBox quizPanel;
    @FXML private Label questionLabel;
    @FXML private TextArea codeSnippetArea;
    @FXML private VBox answerOptions;
    
    @FXML private VBox resultPanel;
    @FXML private Label resultLabel;
    @FXML private Label explanationLabel;
    @FXML private Button nextQuestionButton;
    @FXML private Button finishQuizButton;
    
    // 内置题库
    private final Map<String, List<CodeQuestion>> questionBank = new HashMap<>();
    private List<CodeQuestion> currentQuestions;
    private int currentQuestionIndex = 0;
    private int correctAnswers = 0;
    private MainController mainController;
    
    @FXML
    public void initialize() {
        // 初始化编程语言选项
        languageCombo.setItems(FXCollections.observableArrayList(
            "Java", "Python", "JavaScript", "C++", "C#"
        ));
        languageCombo.getSelectionModel().selectFirst();
        
        // 初始化题目数量选项
        questionCountCombo.setItems(FXCollections.observableArrayList(5, 10, 15, 20));
        questionCountCombo.getSelectionModel().selectFirst();
        
        // 初始化内置题库
        initializeQuestionBank();
    }
    
    public void setMainController(MainController mainController) {
        this.mainController = mainController;
    }
    
    private void initializeQuestionBank() {
        // Java题目
        List<CodeQuestion> javaQuestions = Arrays.asList(
            new CodeQuestion(
                "以下哪个是Java中的基本数据类型？",
                "public class Test {\n    public static void main(String[] args) {\n        // 选择正确的数据类型\n    }\n}",
                Arrays.asList("String", "int", "Object", "ArrayList"),
                1,
                "int是Java中的基本数据类型，用于表示整数。String、Object、ArrayList都是引用类型。"
            ),
            new CodeQuestion(
                "Java中如何声明一个常量？",
                "public class Constants {\n    // 如何声明一个不可变的常量？\n}",
                Arrays.asList("const int MAX = 100", "final int MAX = 100", "static int MAX = 100", "int MAX = 100"),
                1,
                "在Java中使用final关键字声明常量，final int MAX = 100表示MAX是一个不可变的常量。"
            ),
            new CodeQuestion(
                "以下哪个方法用于字符串连接？",
                "String str1 = \"Hello\";\nString str2 = \"World\";\n// 如何连接两个字符串？",
                Arrays.asList("str1.add(str2)", "str1.concat(str2)", "str1.join(str2)", "str1.merge(str2)"),
                1,
                "String类的concat()方法用于字符串连接，也可以使用+运算符。"
            ),
            new CodeQuestion(
                "Java中如何创建线程？",
                "// 选择正确的线程创建方式",
                Arrays.asList("new Thread()", "extends Thread", "implements Thread", "以上都可以"),
                3,
                "Java中可以通过继承Thread类、实现Runnable接口或使用Thread构造函数来创建线程。"
            ),
            new CodeQuestion(
                "以下哪个是Java集合框架中的接口？",
                "// 选择正确的集合接口",
                Arrays.asList("ArrayList", "LinkedList", "List", "HashMap"),
                2,
                "List是接口，ArrayList、LinkedList、HashMap都是具体的实现类。"
            )
        );
        
        // Python题目
        List<CodeQuestion> pythonQuestions = Arrays.asList(
            new CodeQuestion(
                "Python中如何定义函数？",
                "# 选择正确的函数定义语法",
                Arrays.asList("function myFunc():", "def myFunc():", "func myFunc():", "define myFunc():"),
                1,
                "Python使用def关键字定义函数，语法为def 函数名():"
            ),
            new CodeQuestion(
                "Python中如何创建列表？",
                "# 选择正确的列表创建方式",
                Arrays.asList("list = []", "list = ()", "list = {}", "list = <<>>"),
                0,
                "Python中空列表用[]表示，()表示元组，{}表示字典。"
            ),
            new CodeQuestion(
                "Python中如何导入模块？",
                "# 选择正确的导入语法",
                Arrays.asList("import module", "include module", "require module", "using module"),
                0,
                "Python使用import关键字导入模块，语法为import 模块名。"
            ),
            new CodeQuestion(
                "Python中如何判断变量类型？",
                "x = 42\n# 如何判断x的类型？",
                Arrays.asList("type(x)", "typeof(x)", "getType(x)", "x.type()"),
                0,
                "Python使用type()函数获取变量的类型。"
            ),
            new CodeQuestion(
                "Python中如何创建字典？",
                "# 选择正确的字典创建方式",
                Arrays.asList("dict = []", "dict = ()", "dict = {}", "dict = <<>>"),
                2,
                "Python中字典用{}表示，包含键值对。"
            )
        );
        
        // JavaScript题目
        List<CodeQuestion> jsQuestions = Arrays.asList(
            new CodeQuestion(
                "JavaScript中如何声明变量？",
                "// 选择正确的变量声明方式",
                Arrays.asList("var x = 10", "let x = 10", "const x = 10", "以上都可以"),
                3,
                "JavaScript中var、let、const都可以声明变量，但作用域和可变性不同。"
            ),
            new CodeQuestion(
                "JavaScript中如何定义函数？",
                "// 选择正确的函数定义方式",
                Arrays.asList("function myFunc() {}", "const myFunc = () => {}", "let myFunc = function() {}", "以上都可以"),
                3,
                "JavaScript支持多种函数定义方式：函数声明、箭头函数、函数表达式。"
            ),
            new CodeQuestion(
                "JavaScript中如何检查数组？",
                "let arr = [1, 2, 3];\n// 如何检查arr是否为数组？",
                Arrays.asList("arr.isArray()", "Array.isArray(arr)", "arr.type()", "typeof arr"),
                1,
                "使用Array.isArray()方法检查变量是否为数组。"
            ),
            new CodeQuestion(
                "JavaScript中如何添加数组元素？",
                "let arr = [1, 2];\n// 如何添加元素3？",
                Arrays.asList("arr.add(3)", "arr.push(3)", "arr.append(3)", "arr.insert(3)"),
                1,
                "JavaScript使用push()方法向数组末尾添加元素。"
            ),
            new CodeQuestion(
                "JavaScript中如何获取对象属性？",
                "let obj = {name: 'John'};\n// 如何获取name属性？",
                Arrays.asList("obj.name", "obj['name']", "obj.get('name')", "以上都可以"),
                3,
                "JavaScript中可以通过点号或方括号访问对象属性。"
            )
        );
        
        questionBank.put("Java", javaQuestions);
        questionBank.put("Python", pythonQuestions);
        questionBank.put("JavaScript", jsQuestions);
        
        // 为其他语言添加一些通用题目
        List<CodeQuestion> generalQuestions = Arrays.asList(
            new CodeQuestion(
                "什么是面向对象编程？",
                "// 选择正确的描述",
                Arrays.asList("一种编程范式", "一种编程语言", "一种开发工具", "一种数据库"),
                0,
                "面向对象编程是一种编程范式，强调对象的概念和对象之间的交互。"
            ),
            new CodeQuestion(
                "什么是递归？",
                "// 选择正确的描述",
                Arrays.asList("函数调用自身", "循环结构", "条件判断", "异常处理"),
                0,
                "递归是指函数调用自身的编程技术，常用于解决可以分解为相似子问题的问题。"
            )
        );
        
        questionBank.put("C++", generalQuestions);
        questionBank.put("C#", generalQuestions);
    }
    
    @FXML
    private void startQuiz() {
        String selectedLanguage = languageCombo.getValue();
        Integer selectedCount = questionCountCombo.getValue();
        
        if (selectedLanguage == null || selectedCount == null) {
            showAlert("请选择编程语言和题目数量");
            return;
        }
        
        List<CodeQuestion> availableQuestions = questionBank.get(selectedLanguage);
        if (availableQuestions == null || availableQuestions.isEmpty()) {
            showAlert("该编程语言暂无题目");
            return;
        }
        
        // 随机选择题目
        currentQuestions = new ArrayList<>(availableQuestions);
        Collections.shuffle(currentQuestions);
        
        // 限制题目数量
        if (currentQuestions.size() > selectedCount) {
            currentQuestions = currentQuestions.subList(0, selectedCount);
        }
        
        currentQuestionIndex = 0;
        correctAnswers = 0;
        
        quizPanel.setVisible(true);
        showQuestion();
    }
    
    private void showQuestion() {
        if (currentQuestionIndex >= currentQuestions.size()) {
            finishQuiz();
            return;
        }
        
        CodeQuestion question = currentQuestions.get(currentQuestionIndex);
        questionLabel.setText(String.format("题目 %d / %d", currentQuestionIndex + 1, currentQuestions.size()));
        codeSnippetArea.setText(question.getQuestion() + "\n\n" + question.getCodeSnippet());
        
        // 创建答案选项
        answerOptions.getChildren().clear();
        ToggleGroup toggleGroup = new ToggleGroup();
        
        for (int i = 0; i < question.getOptions().size(); i++) {
            RadioButton radioButton = new RadioButton(question.getOptions().get(i));
            radioButton.setToggleGroup(toggleGroup);
            radioButton.setUserData(i);
            answerOptions.getChildren().add(radioButton);
        }
        
        resultPanel.setVisible(false);
        nextQuestionButton.setDisable(false);
    }
    
    @FXML
    private void nextQuestion() {
        // 检查是否选择了答案
        ToggleGroup toggleGroup = null;
        for (javafx.scene.Node node : answerOptions.getChildren()) {
            if (node instanceof RadioButton) {
                RadioButton rb = (RadioButton) node;
                if (rb.getToggleGroup() != null) {
                    toggleGroup = rb.getToggleGroup();
                    break;
                }
            }
        }
        
        if (toggleGroup == null || toggleGroup.getSelectedToggle() == null) {
            showAlert("请选择一个答案");
            return;
        }
        
        // 检查答案
        RadioButton selectedButton = (RadioButton) toggleGroup.getSelectedToggle();
        int selectedAnswer = (Integer) selectedButton.getUserData();
        
        CodeQuestion currentQuestion = currentQuestions.get(currentQuestionIndex);
        if (selectedAnswer == currentQuestion.getCorrectAnswer()) {
            correctAnswers++;
        }
        
        // 显示答案解释
        showAnswerExplanation(currentQuestion, selectedAnswer);
        
        // 禁用下一题按钮，防止重复点击
        nextQuestionButton.setDisable(true);
        
        // 延迟后进入下一题
        PauseTransition pause = new PauseTransition(Duration.seconds(2));
        pause.setOnFinished(event -> {
            currentQuestionIndex++;
            if (currentQuestionIndex >= currentQuestions.size()) {
                finishQuiz();
            } else {
                showQuestion();
                nextQuestionButton.setDisable(false);
            }
        });
        pause.play();
    }
    
    private void showAnswerExplanation(CodeQuestion question, int selectedAnswer) {
        boolean isCorrect = selectedAnswer == question.getCorrectAnswer();
        String result = isCorrect ? "✓ 回答正确！" : "✗ 回答错误！";
        result += "\n\n正确答案：" + question.getOptions().get(question.getCorrectAnswer());
        result += "\n\n解释：" + question.getExplanation();
        
        questionLabel.setText(result);
        answerOptions.getChildren().clear();
        resultPanel.setVisible(true);
    }
    
    @FXML
    private void finishQuiz() {
        double percentage = (double) correctAnswers / currentQuestions.size() * 100;
        String result = String.format("测验完成！\n正确题目：%d / %d\n正确率：%.1f%%", 
                                    correctAnswers, currentQuestions.size(), percentage);
        
        questionLabel.setText("测验完成");
        codeSnippetArea.setText(result);
        answerOptions.getChildren().clear();
        resultPanel.setVisible(false);
        
        // 显示最终结果
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("测验结果");
        alert.setHeaderText("恭喜完成测验！");
        alert.setContentText(result);
        alert.showAndWait();
        
        // 重置到开始状态
        quizPanel.setVisible(false);
    }
    
    private void showAlert(String message) {
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("提示");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
    
    @FXML
    private void goBack() {
        if (mainController != null) {
            mainController.showMainView();
        } else {
            LOGGER.warning("主控制器引用为空，无法返回主页");
        }
    }
    
    // 内部类：代码题目
    private static class CodeQuestion {
        private final String question;
        private final String codeSnippet;
        private final List<String> options;
        private final int correctAnswer;
        private final String explanation;
        
        public CodeQuestion(String question, String codeSnippet, List<String> options, 
                          int correctAnswer, String explanation) {
            this.question = question;
            this.codeSnippet = codeSnippet;
            this.options = options;
            this.correctAnswer = correctAnswer;
            this.explanation = explanation;
        }
        
        public String getQuestion() { return question; }
        public String getCodeSnippet() { return codeSnippet; }
        public List<String> getOptions() { return options; }
        public int getCorrectAnswer() { return correctAnswer; }
        public String getExplanation() { return explanation; }
    }
}
